// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie;

import java.util.ArrayList;
import zombie.characters.IsoPlayer;
import zombie.core.network.ByteBufferWriter;
import zombie.core.raknet.UdpConnection;
import zombie.inventory.CompressIdenticalItems;
import zombie.inventory.InventoryItem;
import zombie.inventory.ItemContainer;
import zombie.inventory.ItemPickerJava;
import zombie.iso.BuildingDef;
import zombie.iso.IsoChunk;
import zombie.iso.IsoChunkMap;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoMetaGrid;
import zombie.iso.IsoObject;
import zombie.iso.IsoWorld;
import zombie.iso.objects.IsoCompost;
import zombie.iso.objects.IsoDeadBody;
import zombie.iso.objects.IsoThumpable;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.PacketTypes;
import zombie.network.ServerMap;
import zombie.network.ServerOptions;

public final class LootRespawn {
    private static int LastRespawnHour = -1;
    private static final ArrayList<InventoryItem> existingItems = new ArrayList();
    private static final ArrayList<InventoryItem> newItems = new ArrayList();

    public static void update() {
        if (!GameClient.bClient) {
            int int0 = getRespawnInterval();
            if (int0 > 0) {
                int int1 = 7 + (int)(zombie.GameTime.getInstance().getWorldAgeHours() / (double)int0) * int0;
                if (LastRespawnHour < int1) {
                    LastRespawnHour = int1;
                    if (GameServer.bServer) {
                        for (int int2 = 0; int2 < ServerMap.instance.LoadedCells.size(); int2++) {
                            ServerMap.ServerCell serverCell = (ServerMap.ServerCell)ServerMap.instance.LoadedCells.get(int2);
                            if (serverCell.bLoaded) {
                                for (int int3 = 0; int3 < 5; int3++) {
                                    for (int int4 = 0; int4 < 5; int4++) {
                                        IsoChunk isoChunk0 = serverCell.chunks[int4][int3];
                                        checkChunk(isoChunk0);
                                    }
                                }
                            }
                        }
                    } else {
                        for (int int5 = 0; int5 < IsoPlayer.numPlayers; int5++) {
                            IsoChunkMap isoChunkMap = IsoWorld.instance.CurrentCell.ChunkMap[int5];
                            if (!isoChunkMap.ignore) {
                                for (int int6 = 0; int6 < IsoChunkMap.ChunkGridWidth; int6++) {
                                    for (int int7 = 0; int7 < IsoChunkMap.ChunkGridWidth; int7++) {
                                        IsoChunk isoChunk1 = isoChunkMap.getChunk(int7, int6);
                                        checkChunk(isoChunk1);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public static void Reset() {
        LastRespawnHour = -1;
    }

    public static void chunkLoaded(IsoChunk chunk) {
        if (!GameClient.bClient) {
            checkChunk(chunk);
        }
    }

    private static void checkChunk(IsoChunk isoChunk) {
        if (isoChunk != null) {
            int int0 = getRespawnInterval();
            if (int0 > 0) {
                if (!(zombie.GameTime.getInstance().getWorldAgeHours() < (double)int0)) {
                    int int1 = 7 + (int)(zombie.GameTime.getInstance().getWorldAgeHours() / (double)int0) * int0;
                    if (isoChunk.lootRespawnHour > int1) {
                        isoChunk.lootRespawnHour = int1;
                    }

                    if (isoChunk.lootRespawnHour < int1) {
                        isoChunk.lootRespawnHour = int1;
                        respawnInChunk(isoChunk);
                    }
                }
            }
        }
    }

    private static int getRespawnInterval() {
        if (GameServer.bServer) {
            return ServerOptions.instance.HoursForLootRespawn.getValue();
        } else {
            if (!GameClient.bClient) {
                int _int = zombie.SandboxOptions.instance.LootRespawn.getValue();
                if (_int == 1) {
                    return 0;
                }

                if (_int == 2) {
                    return 24;
                }

                if (_int == 3) {
                    return 168;
                }

                if (_int == 4) {
                    return 720;
                }

                if (_int == 5) {
                    return 1440;
                }
            }

            return 0;
        }
    }

    private static void respawnInChunk(IsoChunk isoChunk) {
        boolean _boolean = GameServer.bServer && ServerOptions.instance.ConstructionPreventsLootRespawn.getValue();
        int int0 = zombie.SandboxOptions.instance.SeenHoursPreventLootRespawn.getValue();
        double _double = zombie.GameTime.getInstance().getWorldAgeHours();

        for (int int1 = 0; int1 < 10; int1++) {
            for (int int2 = 0; int2 < 10; int2++) {
                IsoGridSquare isoGridSquare = isoChunk.getGridSquare(int2, int1, 0);
                IsoMetaGrid.Zone zone = isoGridSquare == null ? null : isoGridSquare.getZone();
                if (zone != null
                    && ("TownZone".equals(zone.getType()) || "TownZones".equals(zone.getType()) || "TrailerPark".equals(zone.getType()))
                    && (!_boolean || !zone.haveConstruction)
                    && (int0 <= 0 || !(zone.getHoursSinceLastSeen() <= (float)int0))) {
                    if (isoGridSquare.getBuilding() != null) {
                        BuildingDef buildingDef = isoGridSquare.getBuilding().getDef();
                        if (buildingDef != null) {
                            if ((double)buildingDef.lootRespawnHour > _double) {
                                buildingDef.lootRespawnHour = 0;
                            }

                            if (buildingDef.lootRespawnHour < isoChunk.lootRespawnHour) {
                                buildingDef.setKeySpawned(0);
                                buildingDef.lootRespawnHour = isoChunk.lootRespawnHour;
                            }
                        }
                    }

                    for (int int3 = 0; int3 < 8; int3++) {
                        isoGridSquare = isoChunk.getGridSquare(int2, int1, int3);
                        if (isoGridSquare != null) {
                            int int4 = isoGridSquare.getObjects().size();
                            IsoObject[] isoObject0 = isoGridSquare.getObjects().getElements();

                            for (int int5 = 0; int5 < int4; int5++) {
                                IsoObject isoObject1 = isoObject0[int5];
                                if (!(isoObject1 instanceof IsoDeadBody) && !(isoObject1 instanceof IsoThumpable) && !(isoObject1 instanceof IsoCompost)) {
                                    for (int int6 = 0; int6 < isoObject1.getContainerCount(); int6++) {
                                        ItemContainer itemContainer = isoObject1.getContainerByIndex(int6);
                                        if (itemContainer.bExplored && itemContainer.isHasBeenLooted()) {
                                            respawnInContainer(isoObject1, itemContainer);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private static void respawnInContainer(IsoObject isoObject, ItemContainer itemContainer) {
        if (itemContainer != null && itemContainer.getItems() != null) {
            int int0 = itemContainer.getItems().size();
            int int1 = 5;
            if (GameServer.bServer) {
                int1 = ServerOptions.instance.MaxItemsForLootRespawn.getValue();
            }

            if (int0 < int1) {
                existingItems.clear();
                existingItems.addAll(itemContainer.getItems());
                ItemPickerJava.fillContainer(itemContainer, null);
                ArrayList arrayList = itemContainer.getItems();
                if (arrayList != null && int0 != arrayList.size()) {
                    itemContainer.setHasBeenLooted(false);
                    newItems.clear();

                    for (int int2 = 0; int2 < arrayList.size(); int2++) {
                        InventoryItem inventoryItem = (InventoryItem)arrayList.get(int2);
                        if (!existingItems.contains(inventoryItem)) {
                            newItems.add(inventoryItem);
                            inventoryItem.setAge(0.0F);
                        }
                    }

                    ItemPickerJava.updateOverlaySprite(isoObject);
                    if (GameServer.bServer) {
                        for (int int3 = 0; int3 < GameServer.udpEngine.connections.size(); int3++) {
                            UdpConnection udpConnection = (UdpConnection)GameServer.udpEngine.connections.get(int3);
                            if (udpConnection.RelevantTo((float)isoObject.square.x, (float)isoObject.square.y)) {
                                ByteBufferWriter byteBufferWriter = udpConnection.startPacket();
                                PacketTypes.PacketType.AddInventoryItemToContainer.doPacket(byteBufferWriter);
                                byteBufferWriter.putShort((short)2);
                                byteBufferWriter.putInt((int)isoObject.getX());
                                byteBufferWriter.putInt((int)isoObject.getY());
                                byteBufferWriter.putInt((int)isoObject.getZ());
                                byteBufferWriter.putByte((byte)isoObject.getObjectIndex());
                                byteBufferWriter.putByte((byte)isoObject.getContainerIndex(itemContainer));

                                try {
                                    CompressIdenticalItems.save(byteBufferWriter.bb, newItems, null);
                                } catch (Exception exception) {
                                    exception.printStackTrace();
                                }

                                PacketTypes.PacketType.AddInventoryItemToContainer.send(udpConnection);
                            }
                        }
                    }
                }
            }
        }
    }
}
